package java8._06_使用流收集数据;

import org.junit.Test;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class _06_test_质数 {

    public static class CollectorHarness {
        public static void main(String[] args) {
            long fastest = Long.MAX_VALUE;
            for (int i = 0; i < 10; i++) {
                long start = System.nanoTime();
                partitionPrimes(2_000_000);
                long duration = (System.nanoTime() - start) / 1_000_000;
                if (duration < fastest) fastest = duration;
            }
            System.out.println(
                "Fastest execution done in " + fastest + " msecs");
        }

        public static void main2(String[] args) {
            long fastest = Long.MAX_VALUE;
            for (int i = 0; i < 10; i++) {
                long start = System.nanoTime();
                partitionPrimes2(2_000_000);
                long duration = (System.nanoTime() - start) / 1_000_000;
                if (duration < fastest) fastest = duration;
            }
            System.out.println(
                "Fastest execution done in " + fastest + " msecs");
        }

        public static void main3(String[] args) {
            long fastest = Long.MAX_VALUE;
            for (int i = 0; i < 10; i++) {
                long start = System.nanoTime();
                partitionPrimes3(2_000_000);
                long duration = (System.nanoTime() - start) / 1_000_000;
                if (duration < fastest) fastest = duration;
            }
            System.out.println(
                "Fastest execution done in " + fastest + " msecs");
        }

        public static Map<Boolean, List<Integer>> partitionPrimes(int n) {
            return IntStream.rangeClosed(2, n).boxed()
                .collect(new _05_MyListCollector(null));
        }

        public static Map<Boolean, List<Integer>> partitionPrimes2(int n) {
            return IntStream.rangeClosed(2, n).boxed()
                .collect(Collectors.partitioningBy(candidate -> isPrime(candidate)));
        }
        public static boolean isPrime(int candidate) {
            int candidateRoot = (int) Math.sqrt((double) candidate);
            return IntStream.rangeClosed(2, candidateRoot)
                .noneMatch(i -> candidate % i == 0);
        }


        public static Map<Boolean, List<Integer>> partitionPrimes3(int n) {
            _05_MyListCollector mlc = new _05_MyListCollector(null);
            return IntStream.rangeClosed(2, n).boxed()
                .collect(mlc.supplier(),
                    mlc.accumulator(),
                    (map1, map2) -> mlc.combiner().apply(map1, map2));
        }

    }
    @Test
    public void test1() {
        CollectorHarness.main(null);
        CollectorHarness.main2(null);
        CollectorHarness.main3(null);
    }

}
